<template>
  <div id="audio"></div>
  <Row>
    <Col :span="12">
    <Table :columns="rooms.columns" :data="rooms.tableData"></Table>
    </Col>
    <Col :span="12">
    <div class="form" v-show="status">
      <Form :model="formModel" label-position="right" :label-width="90">
        <Form-item label="房间名称:">
          <Input v-model="formModel.roomName" placeholder="输入房间名称" style="width: 300px" />
        </Form-item>
        <Form-item label="用户编码:">
          <Input v-model="formModel.userId" placeholder="输入用户编码" style="width: 300px" />
        </Form-item>
        <Form-item label="选项:">
          <RadioGroup v-model="formModel.creatRoom">
            <Radio label="0">
              <span>创建房间</span>
            </Radio>
            <Radio label="1">
              <span>加入房间</span>
            </Radio>
          </RadioGroup>
        </Form-item>
        <Button type="primary" @click="joinRoomBtn">{{
          formModel.creatRoom === "0" ? "创建房间" : "加入房间"
        }}</Button>
      </Form>
    </div>
    </Col>
  </Row>


  <div v-if="!status" class="form">
    <Result type="success" :title="formModel.roomName" desc="已加入房间" />
    <Input v-model="msgDate.some"></Input>
    <Button @click="postMessage" type="success">发送文本消息</Button>
  </div>
</template>

<script setup>
import { reactive, ref, onMounted } from "vue";
import { Message } from 'view-ui-plus'

import { getToken, getRoomList } from "@/api/index"

import {
  Room,
  // connect,
  RoomEvent,
} from "livekit-client";

// liveKit 服务 链接参数
const wsURL = "ws://127.0.0.1:7880";

// const wsURL = "ws://livekit.arongwang.xyz";


let token = "";
const room = new Room();

// 表单变量
const formModel = reactive({});

// 页面状态
let status = ref(true);

// 表格数据
let rooms = reactive({
  columns: [
    {
      title: "房间名称",
      key: "name",
    },
    {
      title: "空房间关闭时间",
      key: "empty_timeout",
    },
    {
      title: "最大参与人数",
      key: "max_participants",
    },
    {
      title: "创建时间",
      key: "creation_time",
    },
    {
      title: "口令",
      key: "turn_password",
    },
    {
      title: "当前人数",
      key: "num_participants",
    },
  ],
  tableData: [],
});
onMounted(async () => {
  getRoomsList();
});

// 获取房间列表
function getRoomsList() {
  getRoomList().then(res => {
    if (res.rooms) {
      rooms.tableData = res.rooms;
    }
  })
}

// 获取token
function joinRoomBtn() {
  getToken(formModel).then(res => {
    // 请求成功，处理响应数据
    console.log("token", res);
    token = res;
    clientRoom();
    getRoomsList();
  })

}

// 链接到房间
async function clientRoom() {
  await room.connect(wsURL, token)

  if (room.name && room.name.length > 0) {
    // 改变页面状态
    status.value = false;
    console.log("上传音频流");
    uploadAudio();
  }
}

// 上传音频到房间
function uploadAudio() {
  navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
    Message.success({
      background: true,
      content: '已授权麦克风'
    });
    room.localParticipant.setMicrophoneEnabled(true).then(() => {
      console.log("有麦克风");
      Message.success({
        background: true,
        content: '检测到麦克风，开始传入音频'
      });
    })
      .catch(function (error) {
        console.log("没有麦克风或访问被拒绝");
        Message.error({
          background: true,
          content: '没有麦克风或访问麦克风被拒绝'
        });
      });
  })
    .catch(() => {
      Message.error({
        background: true,
        content: '麦克风授权失败'
      });
    })

}

// 监听消息传入
room.on(RoomEvent.TrackSubscribed, handleTrackSubscribed);

// 断开链接/链接失败
room.on(RoomEvent.Disconnected, () => {
  console.log("断开连接/链接失败")
  Message.error({
    background: true,
    content: '断开连接/链接失败'
  });
});

// 重新连接成功
room.on(RoomEvent.Reconnected, () => {
  console.log("已重新连接到房间")
  Message.success({
    background: true,
    content: '已重新连接到房间'
  });
});

// 当前扬声器已更改
room.on(RoomEvent.ActiveSpeakersChanged, () => {
  console.log("扬声器播放了声音")
  // Message.success({
  //   background: true,
  //   content: '扬声器播放了声音'
  // });
});

// 消息传入回调
function handleTrackSubscribed(track, publication, participant) {
  // 将音频附加到新的HTMLAudioElement
  const element = track.attach();
  let audioDom = document.getElementById("audio");
  audioDom.appendChild(element);
  // 加到现有的元素上
  // track.attach(element)
}

// 向Room发送消息
let msgDate = reactive({
  some: ''
})
const encoder = new TextEncoder()
const decoder = new TextDecoder()

/* 发送自定义消息
* @param data {Uint8Array} 消息体
* @param {
          reliable {Boolean}    可靠消息类型
          destinationIdentities {Array} 接收人数组
        } 
*/
function postMessage() {
  let strData = JSON.stringify(msgDate)
  // 消息格式转成 Uint8Array
  const data = encoder.encode(strData);
  room.localParticipant.publishData(data, { reliable: true })
}


/* 接收输入消息
* @return payload {Uint8Array} 消息体
* @return participant  发送者
* @return kind  消息类型
*/
room.on(RoomEvent.DataReceived, (payload, participant, kind) => {
  // 格式转换
  const strData = decoder.decode(payload)
  console.log("接收到消息", strData)
})

// 麦克风静音
// await room.localParticipant.setMicrophoneEnabled(false)

// 同时发布麦克风和摄像头
// await room.localParticipant.enableCameraAndMicrophone();
</script>

<style>
.form {
  margin: 20px auto;
  width: 200px;
}
</style>
